<template>
  <zero-dialog :showDialog.sync="dialog.open" :width="dialog.width" :title="dialog.title"
               :fullscreen.sync="dialog.fullscreen" :id="dialog.id"
               :submit="submitForm">
    <div slot="body">
      <!-- 用户导入对话框 -->
      <el-upload :ref="upload.ref" :limit="upload.limit"
                 :accept="upload.accept" :action="upload.action"
                 :http-request="importSonCodeRequest" :on-exceed="handleExceed"
                 :auto-upload="upload.autoUpload" drag>
        <i class="el-icon-upload"></i>
        <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
        <div class="el-upload__tip text-center" slot="tip">
          <div class="el-upload__tip" slot="tip">
            <el-checkbox v-model="upload.updateSupport"/>
            是否更新已经存在的数据
          </div>
          <span>仅允许导入{{ upload.accept }}格式文件。</span>
          <el-link type="primary" :underline="false"
                   style="font-size:12px;vertical-align: baseline;"
                   @click="importTemplate">下载模板
          </el-link>
        </div>
      </el-upload>
    </div>
  </zero-dialog>
</template>


<script>
import {getToken, getTokenKey} from "@/utils/auth";
import {Loading} from "element-ui";

export default {
  name: 'ZeroImportExport',
  props: {
    searchForm: Object,
    exportUrl: String,
    importUrl: String,
    importTemplateUrl: String,
    getDataList: {
      type: Function,
      default: null
    },
  },
  data() {
    return {
      axios: this.$axiosAuth, // 请求的微服务，默认授权服务
      dialog: {//弹框数据
        id: "importDialogId",
        fullscreen: false, // 弹框全屏
        open: false,//是否弹出表单
        title: '',//标题
        width: '400px', //定义宽度，默认400px
      },
      upload: {//上传数据
        ref: 'importUploadRef',
        action: '#',//屏蔽组件提交
        limit: 1,//可以传几个
        accept: '.xlsx,.xls,.csv',//支持的文件类型,当为空时代表不限制
        autoUpload: false,//不自动上传
        updateSupport: false, // 是否更新已经存在的数据
      },
    }
  },
  methods: {
    //按钮点击事件
    initDialog(params) {
      this.dialog.title = params.title || "导入";
      this.dialog.open = true;
      this.$nextTick(() => {
        this.$refs[this.upload.ref].clearFiles()
      });
    },
    // 开始上传
    importSonCodeRequest(option) {
      let name = option.file.name;
      let dotIndex = name.lastIndexOf('.');
      let extension = name.substring(dotIndex);
      if (this.upload.accept && !this.upload.accept.split(',').includes(extension)) {
        this.$modal.msgError(`文件类型错误，仅支持[${this.upload.accept}]文件类型`);
        return
      }
      //弹框的loading
      let uploadLoadingInstance = this.$loading({target: `#${this.dialog.id} >div >.el-dialog`});
      let data = new FormData()
      data.append("file", option.file)

      let config = {
        url: this.importUrl + `?updateSupport=${this.upload.updateSupport}`,
        method: "post",
        data: data,
        headers: {[getTokenKey()]: "Bearer " + getToken(), 'Content-Type': 'multipart/form-data'},
      }
      this.axios(config).then(res => {
        if (res.data.failCount > 0) {
          //再次弹框
          this.$confirm(`导入成功:${res.data.successCount}条<br/>导入失败:${res.data.failCount}条`, '提示', {
            confirmButtonText: '下载失败文件', cancelButtonText: '取消',
            type: 'warning',
            closeOnClickModal: false,
            closeOnPressEscape: false,
            dangerouslyUseHTMLString: true
          }).then(() => {
            // 将 Base64 字符串解码为二进制数据
            const byteCharacters = atob(res.data.failStream);
            // 创建一个 8kb 的 ArrayBuffer
            const byteNumbers = new Array(byteCharacters.length);
            for (let i = 0; i < byteCharacters.length; i++) {
              byteNumbers[i] = byteCharacters.charCodeAt(i);
            }
            const byteArray = new Uint8Array(byteNumbers);

            // 将二进制数据转换为 Blob 对象
            const blob = new Blob([byteArray], {type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});

            // 创建链接并模拟点击来下载文件
            const link = document.createElement('a');
            link.href = URL.createObjectURL(blob);
            link.download = '失败数据.xlsx'; // 你可以根据需要设置文件名
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link); // 清理
            this.dialog.open = false;
          }).catch(() => {
          });
        } else {
          this.$modal.msgSuccess(res.msg);
          this.dialog.open = false;
          this.getDataList()
        }
      }).catch(() => {
      }).finally(() => {
        uploadLoadingInstance.close()
      })
    },
    // 处理选择新的文件
    handleExceed(files, fileList) {
      this.$set(fileList[0], 'raw', files[0]);
      this.$set(fileList[0], 'name', files[0].name);
    },
    // 导出
    handleExport(params) {
      let fileName = params.title
      let flag = params.flag
      let data = this.searchForm
      let downloadLoadingInstance = Loading.service({
        text: "正在下载数据，请稍候",
        spinner: "el-icon-loading",
        background: "rgba(0, 0, 0, 0.7)",
      })
      const config = {
        method: 'post',
        responseType: 'blob',
        data: data
      }
      if (flag) {
        //模版下载
        config.url = this.importTemplateUrl;
      } else {
        //导出数据
        config.url = this.exportUrl;
      }
      this.axios(config)
          .then((res) => {
            // 这里res.data是返回的blob对象
            const blob = new Blob([res], {
              type: 'application/vnd.ms-excel;charset=UTF-8'
            })
            const downloadElement = document.createElement('a')
            const href = window.URL.createObjectURL(blob) // 创建下载的链接
            downloadElement.href = href
            downloadElement.download = fileName + '.xlsx' // 下载后文件名
            document.body.appendChild(downloadElement)
            downloadElement.click() // 点击下载
            document.body.removeChild(downloadElement) // 下载完成移除元素
            window.URL.revokeObjectURL(href) // 释放掉blob对象
          })
          .catch(() => {
          }).finally(() => {
        downloadLoadingInstance.close();
      });
    },
    /** 下载模板操作 */
    importTemplate() {
      this.handleExport({title: `${this.dialog.title}模板`, flag: true})
    },
    // 提交上传文件
    submitForm() {
      this.$refs[this.upload.ref].submit();
    }
  }
}
</script>
